using System;
using System.Collections.Generic;
using Sedge.Core.App;
using Sedge.Core.Configuration.Report;
using Sedge.Core.Configuration.Transport;
using Sedge.Core.Execution.ReportElements;
using Sedge.Core.Globalization;

namespace Sedge.Core.Configuration
{
	public class Suite : ReportableObject
	{
		#region Folders

		public string RootFolder { get; set; }
		public string WorkingFolder { get; set; }
		public string ImagesFolder { get; set; }
		public string FilesFolder { get; set; }
		public string UserFilesFolder { get; set; }
		public string HtmlFilesFolder { get; set; }

		public string ZipFile { get; set; }

		#endregion //Folders

		#region Public Properties

		private Options _options;
		public Options Options
		{
			set { _options = value; }
			get
			{
				if (_options == null)
				{
					_options = new Options(new Dictionary<string, string>());
				}
				return _options;
			}
		}

		public string SearchPath
		{
			get
			{
				return Options.SearchPath();
			}
		}

		/// <summary>
		/// Assembly to search all UI elements
		/// </summary>
		public string UISource
		{
			get
			{
				string source = Options.UISource();
				if (String.IsNullOrEmpty(source))
					source = Branding.DefaultUIAssembly;

				return source;
			}
		}

		private readonly FilesRegistry _filesRegistry;
		public FilesRegistry FilesRegistry
		{
			get { return _filesRegistry; }
		}

		public ITransport Transport { get; set; }
		public ReportableObject SelectedApplication { get; set; }

		private readonly List<ReportableObject> _applications = new List<ReportableObject>();
		/// <summary>
		/// An application to report
		/// </summary>
		public List<ReportableObject> Applications
		{
			get { return _applications; }
		}

		private readonly List<Step> _steps = new List<Step>();
		/// <summary>
		/// Wizard steps
		/// </summary>
		public List<Step> Steps
		{
			get { return _steps; }
		}

		private readonly IDictionary<string, IReportElement> _tempData = new Dictionary<string, IReportElement>();
		/// <summary>
		/// To store temporary data collected in the views
		/// </summary>
		public IDictionary<string, IReportElement> TempData
		{
			get { return _tempData; }
		}

		#endregion //Public Properties

		#region Constructors

		public Suite()
		{
			ZipFile = String.Empty;
			_filesRegistry = new FilesRegistry(this);
		}

		#endregion // Constructors

		#region Public Methods

		public void SelectApplication(string app)
		{
			if (String.IsNullOrEmpty(app))
				return;

			foreach (ReportableObject application in Applications)
			{
				if (application.Caption == app)
				{
					SelectedApplication = application;
					break;
				}
			}
		}

		public void MergeSuiteWithSelectedApp()
		{
			if (SelectedApplication == null)
				return;

			foreach (var property in SelectedApplication.Properties)
			{
				Properties[property.Key] = property.Value;
			}

			foreach (Group group in SelectedApplication.Groups)
			{
				bool found = false;
				foreach (Group suiteGroup in Groups)
				{
					if (suiteGroup.Name == group.Name)
					{
						MergeGroups(group, suiteGroup);
						found = true;
						break;
					}
				}

				if (!found)
				{
					Groups.Add(group);
				}
			}
		}

		private static void MergeGroups(Group appGroup, Group suiteGroup)
		{
			foreach (Page appPage in appGroup.Pages)
			{
				bool found = false;
				foreach (Page suitePage in suiteGroup.Pages)
				{
					if (appPage.Name == suitePage.Name)
					{
						foreach (ISource source in appPage.Sources)
						{
							suitePage.Sources.Add(source);
						}

						found = true;
						break;
					}
				}

				if (!found)
				{
					suiteGroup.Pages.Add(appPage);
				}
			}
		}

		private static bool CleanFolder(string path)
		{
			bool allDeleted = true;

			string[] dirs = Services.FileSystem.Directory.GetDirectories(path);
			foreach (string dir in dirs)
			{
				allDeleted = allDeleted && CleanFolder(dir);
			}

			string[] files = Services.FileSystem.Directory.GetFiles(path);
			foreach (string file in files)
			{
				try
				{
					Services.FileSystem.File.Delete(file);
				}
				catch
				{
					allDeleted = false;
				}
			}

			try
			{
				Services.FileSystem.Directory.Delete(path);
			}
			catch
			{
				allDeleted = false;
			}

			return allDeleted;
		}

		public void CleanUp()
		{
			bool allDeleted;
			try
			{
				allDeleted = CleanFolder(WorkingFolder);
			}
			catch
			{
				allDeleted = false;
			}

			if (!allDeleted)
			{
				Services.Communications.InformUser(Locale.Strings.MsgErrorFilesDelete,
																				Locale.Strings.MsgError);
			}
		}

		#endregion

	}
}